package com.kaigejava.demo.business.service.grab;

import com.fasterxml.jackson.databind.JsonNode;
import com.kaigejava.demo.business.barrgelog.dto.DanMuMsgDTO;
import com.kaigejava.demo.business.barrgelog.entity.BarrageLogEntity;
import com.kaigejava.demo.business.barrgelog.service.IBarrageLogService;
import com.kaigejava.demo.business.enums.TypeEnum;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFutureListener;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import tech.ordinaryroad.live.chat.client.bilibili.client.BilibiliLiveChatClient;
import tech.ordinaryroad.live.chat.client.bilibili.config.BilibiliLiveChatClientConfig;
import tech.ordinaryroad.live.chat.client.bilibili.constant.BilibiliCmdEnum;
import tech.ordinaryroad.live.chat.client.bilibili.listener.IBilibiliMsgListener;
import tech.ordinaryroad.live.chat.client.bilibili.msg.DanmuMsgMsg;
import tech.ordinaryroad.live.chat.client.bilibili.msg.SendGiftMsg;
import tech.ordinaryroad.live.chat.client.bilibili.msg.SendSmsReplyMsg;
import tech.ordinaryroad.live.chat.client.bilibili.msg.SuperChatMessageMsg;
import tech.ordinaryroad.live.chat.client.bilibili.netty.handler.BilibiliBinaryFrameHandler;
import tech.ordinaryroad.live.chat.client.bilibili.netty.handler.BilibiliConnectionHandler;
import tech.ordinaryroad.live.chat.client.commons.base.msg.BaseCmdMsg;
import tech.ordinaryroad.live.chat.client.commons.base.msg.BaseMsg;
import tech.ordinaryroad.live.chat.client.commons.base.msg.IMsg;

import javax.annotation.Resource;

/**
 * @BelongsProject: douyin-live-java
 * @Author: kaigejava
 * @CreateTime: 2023-11-09  16:11
 * @Description: 抓取B站直播弹幕的业务类
 * @Version: 1.0
 */
@Service
@Slf4j
public class BilibiliLiveGrabService extends BaseSendMessageService implements IGrabService{
    static Object lock = new Object();
    BilibiliLiveChatClient client;

    @Resource
    private IBarrageLogService barrageLogService;

  //  static Channel channel;


    @Override
    public void grab(String roomId,long timestamp)  throws InterruptedException {
        String cookie = System.getenv("cookie");
        log.error("cookie: {}", cookie);
        BilibiliLiveChatClientConfig config = BilibiliLiveChatClientConfig.builder()
                // TODO 浏览器Cookie
               // .cookie(cookie)
                .roomId(Long.valueOf(roomId))
                .build();

        client = new BilibiliLiveChatClient(config, new IBilibiliMsgListener() {

            //onDisconnected
            @Override
            public void onDanmuMsg(BilibiliBinaryFrameHandler binaryFrameHandler, DanmuMsgMsg msg) {
                IBilibiliMsgListener.super.onDanmuMsg(binaryFrameHandler, msg);
                log.info("B站- {} 收到弹幕 {}({})：{}", binaryFrameHandler.getRoomId(), msg.getUsername(), msg.getUid(), msg.getContent());
                //将弹幕发送到页面
                String message = "用户昵称【"+msg.getUsername()+"】"+",在【"+currentTime+"】的时候,发送的弹幕内容为:【"+msg.getContent()+"】";
                //入库保存
                DanMuMsgDTO danMuMsgDTO =  DanMuMsgDTO.bilibiliLiveOf(msg,Long.parseLong(roomId));
                barrageLogService.save(danMuMsgDTO,TypeEnum.B_STATION.getCode());
                sendMessage(message, TypeEnum.B_STATION.getCode()+"_"+roomId+"_"+timestamp);
            }

            @Override
            public void onGiftMsg(BilibiliBinaryFrameHandler binaryFrameHandler, SendGiftMsg msg) {
                IBilibiliMsgListener.super.onGiftMsg(binaryFrameHandler, msg);
                // log.info("{} 收到礼物 {}({}) {} {}({})x{}({})", binaryFrameHandler.getRoomId(), msg.getUsername(), msg.getUid(), msg.getData().getAction(), msg.getGiftName(), msg.getGiftId(), msg.getGiftCount(), msg.getGiftPrice());
            }

            @Override
            public void onSuperChatMsg(BilibiliBinaryFrameHandler binaryFrameHandler, SuperChatMessageMsg msg) {
                IBilibiliMsgListener.super.onSuperChatMsg(binaryFrameHandler, msg);
                //  log.info("{} 收到醒目留言 {}({})：{}", binaryFrameHandler.getRoomId(), msg.getUsername(), msg.getUid(), msg.getContent());
            }

            @Override
            public void onEnterRoom(SendSmsReplyMsg msg) {
                //   log.debug("普通用户进入直播间 {}", msg.getData().get("uname").asText());
            }

            @Override
            public void onEntryEffect(SendSmsReplyMsg msg) {
                JsonNode data = msg.getData();
                String copyWriting = data.get("copy_writing").asText();
                // log.info("入场效果 {}", copyWriting);
            }

            @Override
            public void onWatchedChange(SendSmsReplyMsg msg) {
                JsonNode data = msg.getData();
                int num = data.get("num").asInt();
                String textSmall = data.get("text_small").asText();
                String textLarge = data.get("text_large").asText();
                // log.debug("观看人数变化 {} {} {}", num, textSmall, textLarge);
            }

            @Override
            public void onClickLike(SendSmsReplyMsg msg) {
                JsonNode data = msg.getData();
                String uname = data.get("uname").asText();
                String likeText = data.get("like_text").asText();
                // log.debug("为主播点赞 {} {}", uname, likeText);
            }

            @Override
            public void onClickUpdate(SendSmsReplyMsg msg) {
                JsonNode data = msg.getData();
                int clickCount = data.get("click_count").asInt();
                //  log.debug("点赞数更新 {}", clickCount);
            }

            @Override
            public void onMsg(IMsg msg) {
                log.debug("收到{}消息 {}", msg.getClass(), msg);
            }

            @Override
            public void onCmdMsg(BilibiliCmdEnum cmd, BaseCmdMsg<BilibiliCmdEnum> cmdMsg) {
                // log.debug("收到CMD消息{} {}", cmd, cmdMsg);
            }

            @Override
            public void onOtherCmdMsg(BilibiliCmdEnum cmd, BaseCmdMsg<BilibiliCmdEnum> cmdMsg) {
                // log.debug("收到其他CMD消息 {}", cmd);
            }

            @Override
            public void onUnknownCmd(String cmdString, BaseMsg msg) {
                log.debug("收到未知CMD消息 {}", cmdString);
            }
        });
        client.connect();

        // 防止测试时直接退出
        while (true) {
            synchronized (lock) {
                lock.wait();
            }
        }
    }



    @Override
    public void close(String roomId) throws Exception {
        client.disconnect();
        boolean isShutdown = client.getWorkerGroup().isShutdown();
        if(!isShutdown){
            client.getWorkerGroup().shutdownGracefully();
            System.out.println("关闭【B站】连接："+roomId);
        }
    }
}
